package core;

import Interface.Moveable;
import constant.Constant;
import util.GameUtil;
import util.ImageUtil;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.List;

public class MySnake extends Object implements Moveable {

    private int speed;
    private int length;
    private int num;
    public int score = 0;

    private static BufferedImage IMG_SNAKE_HEAD = (BufferedImage) ImageUtil.images.get("snake-head-right");

    private static List<Point> bodyPoints = new LinkedList<>();

    private static BufferedImage newImgSnakeHead;

    boolean up,down,left,right=true;

    public MySnake(int x,int y){
        this.live = true;
        this.x = x;
        this.y = y;
        this.image = ImageUtil.images.get("snake-body");
        this.width = image.getWidth(null);
        this.height = image.getHeight(null);
        this.speed = 5;
        this.length = 1;
        this.num = width/speed;
        newImgSnakeHead = IMG_SNAKE_HEAD;
    }

    public int getLength(){
        return length;
    }
    public void setLength(int length){
        this.length = length;
    }

    public void keyPressed(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
                if (!down){
                    up = true;
                    down = false;
                    left = false;
                    right = false;
                    newImgSnakeHead = (BufferedImage) GameUtil.rotateImage(IMG_SNAKE_HEAD,-90);
                }
                break;
            case KeyEvent.VK_DOWN:
                if (!up){
                    up = false;
                    down = true;
                    left = false;
                    right = false;
                    newImgSnakeHead = (BufferedImage) GameUtil.rotateImage(IMG_SNAKE_HEAD,90);
                }
                break;
            case KeyEvent.VK_LEFT:
                if (!right){
                    up = false;
                    down = false;
                    left = true;
                    right = false;
                    newImgSnakeHead = (BufferedImage)GameUtil.rotateImage(IMG_SNAKE_HEAD,-180);
                }
                break;
            case KeyEvent.VK_RIGHT:
                if (!left){
                    up = false;
                    down = false;
                    left = false;
                    right = true;
                    newImgSnakeHead = IMG_SNAKE_HEAD;
                }
                break;
            default:
                break;
        }
    }

    public void eatBody(){
        for (Point point : bodyPoints) {
            for (Point point2 : bodyPoints){
                if (point.equals(point2)&&point!=point2){
                    this.live = false;
                }
            }
        }
    }

    @Override
    public void draw(Graphics g) {
        outOfBounds();
        eatBody();

        bodyPoints.add(new Point(x,y));

        if (bodyPoints.size()==(this.length+1)*num){
            bodyPoints.remove(0);
        }
        g.drawImage(newImgSnakeHead,x,y,null);
        drawBody(g);
        move();
    }

    private void drawBody(Graphics g) {
        int length = bodyPoints.size()-1-num;
        for (int i=length;i>=num;i-=num){
            Point point = bodyPoints.get(i);
            g.drawImage(image,point.x,point.y,null);
        }
    }

    private void outOfBounds() {
        boolean xOut = (x<=0 || x>= Constant.GAME_WIDTH-width);
        boolean yOut = (y<=0 || y>=Constant.GAME_HEIGHT-height);
        if (xOut||yOut){
            live = false;
        }
    }

    @Override
    public void move() {
        if (up){
            y -= speed;
        }else if (down){
            y += speed;
        }else if (left){
            x -= speed;
        }else if (right){
            x += speed;
        }
    }
}
